<html>
    <head>
        <title>二维变换学习2</title>
        <link rel="stylesheet" type="text/css" href="lib/webgl-tutorials.css">
        <!-- <style>
            body {
                margin: 0;
            }
            canvas {
                width: 100vw;
                height: 100vh;
                display: block;
            }
        </style> -->
    </head>
    <body onload="main()">
        <canvas id = "c"></canvas>
        <div id="uiContainer">
            <div id="ui">
                <div id="x"></div>
                <div id="y"></div>
                <div id="angle"></div>
                <div id="scaleX"></div>
                <div id="scaleY"></div>
                <div id="scaleXY"></div>
            </div>
            </div>
    </body>
    <script type='text/javascript' src="lib/webgl-utils.js"></script>
    <script type='text/javascript' src="lib/webgl-lessons-ui.js"></script>
    <script id="vertex-shader-2d" type="x-shaderx-shader/x-vertex">
        attribute vec2 a_Position;
        //uniform vec2 u_Resolution;
        //uniform vec2 u_Transform;
        uniform mat3 u_Transform;
        void main(){
            //vec2 posiotion = a_Position + u_Transform; 不使用矩阵的平移
            //vec2 posiotion = (u_Transform * vec3(a_Position, 1)).xy;
            //posiotion = posiotion / u_Resolution;
            //posiotion = posiotion * 2.0;
            //posiotion = posiotion - 1.0;
            //posiotion = posiotion * vec2(1 , -1);//y轴倒置
            //gl_Position = vec4(posiotion.xy, 0, 1);
            gl_Position = vec4((u_Transform * vec3(a_Position, 1)).xy, 0, 1);
            gl_PointSize = 5.0;
        }
    </script>
    <script id="fragment-shader-2d" type="x-shader/x-fragment">
        precision mediump float;
        uniform vec4 u_FragColor;
        void main(){
            gl_FragColor = u_FragColor;
        }
    </script>
    <script type="text/javascript">
        var translation = [200, 150];//左上位置
        var angleInRadians = 0;//角度
        var scale = [1, 1];//缩放因子
        var color = [Math.random(), Math.random(), Math.random(), 1]

        function main(){
            var canvas = document.getElementById("c");
            var gl = canvas.getContext("webgl");
            if(!gl){
                error("not supported webgl.");
                return; 
            }

            setupUI();

        
            //编译shader
            var program = webglUtils.createProgramFromScripts(gl, ["vertex-shader-2d", "fragment-shader-2d"]);
            var a_Position = gl.getAttribLocation(program, "a_Position");
            //var u_Resolution = gl.getUniformLocation(program, "u_Resolution");
            var u_Transform = gl.getUniformLocation(program, "u_Transform");
            var u_FragColor = gl.getUniformLocation(program, "u_FragColor");

            //顶点buffer
            var vertexBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
            //设置顶点属性
            setRectangle();

            //drawScene
            drawScene();

            //requestAnimationFrame(animation);

            //测试动画
            function animation(){
                angleInRadians -= 0.01;
                //translation[0] += 0.4;
                //translation[1] += 0.4;
                scale[0] -= 0.001;
                scale[1] -= 0.001;
                drawScene();
                requestAnimationFrame(animation);
            }

            //绘制
            function drawScene(){
                webglUtils.resizeCanvasToDisplaySize(gl.canvas);
                gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

                gl.clearColor(0.0, 0.0, 0.0, 1.0);
                gl.clear(gl.COLOR_BUFFER_BIT);

                gl.useProgram(program);
                gl.enableVertexAttribArray(a_Position);
                gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
                gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false,  0, 0);

                //gl.uniform2f(u_Resolution, gl.canvas.width, gl.canvas.height);
                gl.uniform4fv(u_FragColor, color);
                //gl.uniform2f(u_Transform, translation[0], translation[1]);

                //计算矩阵
                var projectionMatrix = m3.projection(gl.canvas.width, gl.canvas.height);
                // var translationMatrix = m3.translation(translation[0], translation[1]);
                // var rotationMatrix = m3.rotation(angleInRadians);
                // var scaleMatrix = m3.scaling(scale[0], scale[1]);

                // var matrix = m3.multiply(projectionMatrix, translationMatrix);
                // matrix = m3.multiply(matrix, rotationMatrix);
                // matrix = m3.multiply(matrix, scaleMatrix);
                var matrix = m3.translate(projectionMatrix, translation[0], translation[1]);
                matrix = m3.rotate(matrix, angleInRadians);
                matrix = m3.scale(matrix, scale[0], scale[1]);

                gl.uniformMatrix3fv(u_Transform, false, matrix);

                gl.drawArrays(gl.TRIANGLES, 0, 18);
            }

            //顶点属性
            function setRectangle(){
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
                    // 矩形
                    // 0.0, 20.0,
                    // 40.0, 20.0,
                    // 0.0, 0.0,
                    // 40.0, 0.0,
                     // left column 
                    0, 0,
                    30, 0,
                    0, 150,
                    0, 150,
                    30, 0,
                    30, 150,

                    // top rung
                    30, 0,
                    100, 0,
                    30, 30,
                    30, 30,
                    100, 0,
                    100, 30,

                    // middle rung
                    30, 60,
                    67, 60,
                    30, 90,
                    30, 90,
                    67, 60,
                    67, 90,
                ]), gl.STATIC_DRAW);
            }

            function setupUI(){
                webglUtils.resizeCanvasToDisplaySize(gl.canvas);
                webglLessonsUI.setupSlider("#x", {value: translation[0], slide: updatePosition(0), max: gl.canvas.width });
                webglLessonsUI.setupSlider("#y", {value: translation[1], slide: updatePosition(1), max: gl.canvas.height});
                webglLessonsUI.setupSlider("#angle", {value: angleInRadians, slide: updateAngle, max: 360});
                webglLessonsUI.setupSlider("#scaleX", {value: scale[0], slide: updateScale(0), min: -5, max: 5, step: 0.01, precision: 2 });
                webglLessonsUI.setupSlider("#scaleY", {value: scale[1], slide: updateScale(1), min: -5, max: 5, step: 0.01, precision: 2 });
                webglLessonsUI.setupSlider("#scaleXY", {value: scale[0], slide: updateScaleXY, min: -5, max: 5, step: 0.01, precision: 2 });
            }

            function updatePosition(index){
                return function(event, ui) {
                    translation[index] = ui.value;
                    drawScene();
                };
            }

            function updateAngle(event, ui) {
                var angleInDegrees = 360 - ui.value;
                angleInRadians = angleInDegrees * Math.PI / 180
                drawScene();
            }

            function updateScale(index){
                return function(event, ui) {
                    scale[index] = ui.value;
                    drawScene();
                };
            }

            function updateScaleXY(event, ui){
                // return function(event, ui) {
                //     scale[index] = ui.value;
                //     drawScene();
                // };
                scale[0] = ui.value;
                scale[1] = ui.value;
                drawScene();
            }
        }

        var m3 = {
                //坐标转换形成矩阵 
                // ( x / 400) * 2 - 1
                projection: function(width, height){
                    return [
                        2 / width, 0, 0,
                        0, -2 / height, 0,
                        -1, 1, 1
                    ]
                },
                identity: function(){
                    return [
                        1, 0, 0,
                        0, 1, 0,
                        0, 0, 1
                    ]
                },
                translation: function (tx, ty){
                    return [
                        1, 0, 0,
                        0, 1, 0,
                        tx, ty, 1
                    ]
                },
                translate: function (m, tx, ty){
                    return m3.multiply(m, m3.translation(tx, ty));
                },
                rotation: function (radiansAngle){
                    var cos = Math.cos(radiansAngle);
                    var sin = Math.sin(radiansAngle);
                    return [
                        cos, -sin, 0,
                        sin, cos, 0,
                        0, 0, 1
                    ]
                },
                rotate: function (m, radiansAngle){
                    return m3.multiply(m, m3.rotation(radiansAngle));
                },
                scaling: function(sx, sy){
                    return[
                        sx, 0, 0,
                        0, sy, 0,
                        0, 0, 1
                    ]
                },
                scale: function (m, sx, sy){
                    return m3.multiply(m, m3.scaling(sx, sy));
                },
                multiply: function(a, b) {
                    var a00 = a[0 * 3 + 0];
                    var a01 = a[0 * 3 + 1];
                    var a02 = a[0 * 3 + 2];
                    var a10 = a[1 * 3 + 0];
                    var a11 = a[1 * 3 + 1];
                    var a12 = a[1 * 3 + 2];
                    var a20 = a[2 * 3 + 0];
                    var a21 = a[2 * 3 + 1];
                    var a22 = a[2 * 3 + 2];
                    var b00 = b[0 * 3 + 0];
                    var b01 = b[0 * 3 + 1];
                    var b02 = b[0 * 3 + 2];
                    var b10 = b[1 * 3 + 0];
                    var b11 = b[1 * 3 + 1];
                    var b12 = b[1 * 3 + 2];
                    var b20 = b[2 * 3 + 0];
                    var b21 = b[2 * 3 + 1];
                    var b22 = b[2 * 3 + 2];
                    return [
                    b00 * a00 + b01 * a10 + b02 * a20,
                    b00 * a01 + b01 * a11 + b02 * a21,
                    b00 * a02 + b01 * a12 + b02 * a22,
                    b10 * a00 + b11 * a10 + b12 * a20,
                    b10 * a01 + b11 * a11 + b12 * a21,
                    b10 * a02 + b11 * a12 + b12 * a22,
                    b20 * a00 + b21 * a10 + b22 * a20,
                    b20 * a01 + b21 * a11 + b22 * a21,
                    b20 * a02 + b21 * a12 + b22 * a22,
                    ];
                }
            }
    </script>
</html>